package com.luo.demo.common.aop;

import com.alibaba.fastjson.JSON;
import com.luo.demo.common.exception.BusinessException;
import com.luo.demo.common.result.Result;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Aspect
@Component
public class GlobalExceptionHandler {

    @Autowired
    private HttpServletResponse response;

    // 定义切点：拦截所有控制器方法
    @Pointcut("execution(* com.luo.demo.controller..*.*(..))")
    public void controllerMethodsCut() {
    }

    // 环绕通知：统一处理返回结果和异常
    @Around("controllerMethodsCut()")
    public Object handleControllerMethod(ProceedingJoinPoint joinPoint) {
        // 获取当前请求
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        try {
            // 执行目标方法
            return joinPoint.proceed();
        } catch (BusinessException e) {
            // 捕获自定义业务异常
            return Result.error(e.getCode(), e.getMessage());
        } catch (Throwable e) {
            // 捕获其他异常
            return Result.error(500, "系统内部错误: " + e.getMessage());
        }
    }

    @AfterThrowing(pointcut = "execution(* com.luo.demo.common..*.*(..)))", throwing = "e")
    public void afterThrowing(Exception e) throws IOException {
        int code = 500; // 默认状态码
        String message = e.getMessage();

        // 如果是自定义的 BusinessException，提取其 code 值
        if (e instanceof BusinessException) {
            BusinessException businessException = (BusinessException) e;
            code = businessException.getCode();
            message = businessException.getMessage();
        }

        // 返回 JSON 响应
        String jsonString = JSON.toJSONString(Result.error(code, message));
        response.setCharacterEncoding("utf8");
        response.setStatus(code); // 设置 HTTP 状态码
        response.setContentType("application/json"); // 设置响应类型为 JSON
        response.getWriter().write(jsonString);
        response.getWriter().close();
    }
}